package org.jflame.devAide.component;

import org.jflame.commons.util.ArrayHelper;
import org.jflame.fx.util.FxUtils;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;

/**
 * 可切换显式的布局面板
 * 
 * @author charles.zhang
 */
public class CardPane extends StackPane {

    private ObjectProperty<Node> showNode = new SimpleObjectProperty<>(this, "showNode");

    public CardPane() {
        this((Node[]) null);
    }

    public CardPane(Node... nodes) {
        super();
        getStyleClass().setAll("card-pane");

        showNode.addListener(showNodeChangedListener);

        ObservableList<Node> childNodes = getChildren();
        if (ArrayHelper.isNotEmpty(nodes)) {
            childNodes.addAll(nodes);
            setShowNode(nodes[0]);
        }
        childNodes.addListener(childChangedListener);
    }

    public void add(Node pane) {
        getChildren().add(pane);
        FxUtils.hide(pane);
    }

    /**
     * 添加并显示面板
     * 
     * @param pane
     */
    public void addAndShow(Node pane) {
        getChildren().add(pane);
        setShowNode(pane);
    }

    public ObjectProperty<Node> showNodeProperty() {
        return showNode;
    }

    public final Node getShowNode() {
        return showNode != null ? showNode.get() : null;
    }

    public void setShowNode(Node showNode) {
        showNodeProperty().set(showNode);
    }

    /**
     * 用css id选择器设置要显示的控件
     * 
     * @param nodeId css id选择器名称,不带#
     */
    public void show(String nodeId) {
        ObservableList<Node> nodes = getChildren();
        if (nodes.isEmpty()) {
            return;
        }
        nodes.forEach(n -> {
            if (nodeId.equals(n.getId())) {
                setShowNode(n);
            }
        });
    }

    // 显示控件修改事件
    ChangeListener<Node> showNodeChangedListener = (observable, oldValue, newValue) -> {

        // System.out.println("changed event, oldValue:" + oldValue + " newValue:" + newValue);
        ObservableList<Node> nodes = getChildren();
        if (nodes.isEmpty()) {
            return;
        }
        for (Node node : nodes) {
            if (newValue == node) {
                FxUtils.show(node);
            } else {
                if (node.isVisible()) {
                    FxUtils.hide(node);
                }
            }
        }
    };

    // 子控件修改事件
    ListChangeListener<Node> childChangedListener = (c) -> {
        if (c.next()) {
            if (c.wasRemoved()) {
                Node curPane = getShowNode();
                // 当前显示控件被删除了,显示第一个
                if (c.getRemoved()
                        .contains(curPane)) {
                    ObservableList<Node> nodes = getChildren();
                    if (nodes.isEmpty()) {
                        setShowNode(null);
                    } else {
                        setShowNode(nodes.get(0));
                    }
                }
            }
        }
    };

}
